/// Custom compression method
///
/// ```
/// # use rusty_leveldb::{Compressor, CompressorId};
///
/// #[derive(Debug, Clone, Copy, Default)]
/// pub struct CustomCompressor;
///
/// impl CompressorId for CustomCompressor {
///     // a unique id to identify what compressor should DB use
///     const ID: u8 = 42;
/// }
///
/// impl Compressor for CustomCompressor {
///     fn encode(&self, block: Vec<u8>) -> rusty_leveldb::Result<Vec<u8>> {
///         // Do something
///         Ok(block)
///     }
///
///     fn decode(&self, block: Vec<u8>) -> rusty_leveldb::Result<Vec<u8>> {
///         // Do something
///         Ok(block)
///     }
/// }
/// ```
///
/// See [crate::CompressorList] for usage
///
/// 定义了压缩器的基本功能，任何压缩算法都需要实现这两个方法：
pub trait Compressor {
    /// 将输入的数据块（Vec<u8>）压缩并返回压缩后的数据
    fn encode(&self, block: Vec<u8>) -> crate::Result<Vec<u8>>;
    /// 将压缩的数据块解压缩并返回原始数据
    fn decode(&self, block: Vec<u8>) -> crate::Result<Vec<u8>>;
}

/// Set default compressor id
pub trait CompressorId {
    /// 为每个压缩器定义一个唯一的标识符（ID），用于在存储或传输时标记使用的压缩算法，以便后续正确解压缩。
    /// const ID: u8：关联常量，存储压缩器的唯一标识（0-255 之间的数值）
    const ID: u8;
}

/// A compressor that do **Nothing**
///
/// It default id is `0`
///
/// 一种特殊的 "压缩器"，实际上不进行任何压缩操作：
///
/// ID 为 0（默认压缩器标识）
///
/// 适用于不需要压缩的场景，或作为默认选项
#[derive(Debug, Clone, Copy, Default)]
pub struct NoneCompressor;

impl CompressorId for NoneCompressor {
    const ID: u8 = 0;
}

impl Compressor for NoneCompressor {
    fn encode(&self, block: Vec<u8>) -> crate::Result<Vec<u8>> {
        Ok(block)
    }

    fn decode(&self, block: Vec<u8>) -> crate::Result<Vec<u8>> {
        Ok(block)
    }
}

/// A compressor that compress data with Google's Snappy
///
/// It default id is `1`
///
/// 使用 Google 的 Snappy 压缩算法进行数据压缩：
///
/// Snappy 算法以压缩速度快为特点，适合对压缩速度要求高的场景
#[derive(Debug, Clone, Copy, Default)]
pub struct SnappyCompressor;

impl CompressorId for SnappyCompressor {
    /// ID 为 1
    const ID: u8 = 1;
}

impl Compressor for SnappyCompressor {
    /// 使用 Snappy 算法压缩数据
    fn encode(&self, block: Vec<u8>) -> crate::Result<Vec<u8>> {
        Ok(snap::raw::Encoder::new().compress_vec(&block)?)
    }
    /// 使用 Snappy 算法解压缩数据
    fn decode(&self, block: Vec<u8>) -> crate::Result<Vec<u8>> {
        Ok(snap::raw::Decoder::new().decompress_vec(&block)?)
    }
}
